// ======================================================================
// Hell Lua Bus ( Lua Bind) Lib
// 
// Copyright 2013 Hell-Prototypes
//
// http://code.google.com/p/hell-prototypes/
//
// This is free software, licensed under the terms of the GNU General
// Public License as published by the Free Software Foundation.
// ======================================================================

#include <usb.h> /* libusb header */
//#include <unistd.h> /* for geteuid */
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

#include "define.h"

static int get_int_value(lua_State *L)
{
    int value;

    if(!lua_isnumber(L, -1)) {
        lua_pop(L, 1);
        return -ERR_PARAM_TYPE;
    }

    value = lua_tointeger(L, -1);
    lua_pop(L, 1);

    if(value < 0) {
        return -ERR_PARAM_VALUE;
    }

    return value;
}

static int get_byte_table_value(lua_State *_L, char * dst, int dst_buf_len)
{
    int table_element_num;
    int ret = 0;

    if(!lua_istable(_L, -1)) {//is table ?
        return -1;
    }

    table_element_num = lua_rawlen(_L, -1);
    if(table_element_num < 1) {
        goto lb_ret;
    }

    for(ret=0; (ret<table_element_num) && (ret<dst_buf_len); ret++) {
        lua_pushinteger(_L, 1+ret);
        lua_gettable(_L, -2);
        if(!lua_isnumber(_L, -1)) {
            goto lb_ret;
        } else {
            dst[ret] = (char)lua_tointeger(_L, -1);
        }
        lua_pop(_L, 1);
    }

lb_ret:
    lua_pop(_L, 1);

    return ret;
}

static int get_int_table_value(lua_State *_L, int * dst, int dst_buf_len)
{
    int table_element_num;
    int ret = 0;

    if(!lua_istable(_L, -1)) {//is table ?
        goto lb_ret;
    }

    table_element_num = lua_rawlen(_L, -1);
    if(table_element_num < 1) {
        goto lb_ret;
    }

    for(ret=0; (ret<table_element_num) && (ret<dst_buf_len); ret++) {
        lua_pushinteger(_L, 1+ret);
        lua_gettable(_L, -2);
        if(!lua_isnumber(_L, -1)) {
            goto lb_ret;
        } else {
            dst[ret] = (int)lua_tointeger(_L, -1);
        }
        lua_pop(_L, 1);
    }

lb_ret:
    lua_pop(_L, 1);

    return ret;
}



static int l_msdelay(lua_State *L)
{
    int i;
    int value = get_int_value(L);;

    if(value > 0) {
        for(i=0; i<value/2; i++) {
            usleep(1000);//bug?
        }

        lua_pushnumber (L, NO_ERR);
    } else {
        lua_pushnumber (L, value);
    }

    return 1;
}

static int l_usdelay(lua_State *L)
{
    int value = get_int_value(L);;

    if(value > 0) {
        usleep(value/2);//bug?

        lua_pushnumber (L, NO_ERR);
    } else {
        lua_pushnumber (L, value);
    }

    return 1;
}
//==============================================================================
static int l_get_fw_version(lua_State *L)
{
	char fw_ver[3];
	
    lua_pop(L, lua_gettop(L));//clear stack

    if(g_usb_dev != NULL) {
        if(	usb_control_msg(g_usb_dev, 0x40 | 0x80, USB_FW_VER, 0x0000, 0x0000,
                                fw_ver, 1, 1000 ) < 0) {
            lua_pushnumber (L, -ERR_CTRL_MSG);
        } else {
            lua_pushnumber (L, fw_ver[0]);
        }
    } else {
        lua_pushnumber (L, -ERR_NO_OPEN);
    }

    return 1;
}
